﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using eeenno.ReaderEngine.Adapters;

namespace eeenno.ReaderEngine.Utilities
{
    /// <summary>
    /// Class that encrypts data
    /// </summary>
    public class Security
    {
        private static SymmetricAlgorithm mCSP;

        /// <summary>
        /// Initializes the Security class (sets Key and IV values)
        /// </summary>
        public static void Initialize()
        {
            mCSP = SymmetricAlgorithm.Create();
            if (Settings.Key.Length > 0 && Settings.Four.Length > 0)
            {
                mCSP.Key = Convert.FromBase64String(Settings.Key);
                mCSP.IV = Convert.FromBase64String(Settings.Four);
            }
            else
            {
                mCSP.GenerateIV();
                mCSP.GenerateKey();
                Settings.Key = Convert.ToBase64String(mCSP.Key);
                Settings.Four = Convert.ToBase64String(mCSP.IV);   
            }
        }

        /// <summary>
        /// Encrypts a string
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string Encrypt(string input)
        {            
            ICryptoTransform ct = null;
            MemoryStream ms = null;
            CryptoStream cs = null;
            byte[] byt;
            try
            {
                ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV);
                byt = Encoding.Default.GetBytes(input);
                ms = new MemoryStream();
                cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
                cs.Write(byt, 0, byt.Length);
                cs.FlushFinalBlock();
                //ret_val = Convert.ToBase64String(ms.ToArray());
            }
            catch (Exception e)
            {
                LogManager.LogError("Security.Encrypt", e.Message);
            }
            finally
            {
                if (cs != null)
                {
                    cs.Close();
                }
                if (ms != null)
                {
                    ms.Close();
                }
                if (ct != null)
                {
                    ct.Dispose();
                }
            }
            return Convert.ToBase64String(ms.ToArray());
        }

        /// <summary>
        /// Decrypts a string
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string Decrypt(string input)
        {
            ICryptoTransform ct = null;
            MemoryStream ms = null;
            CryptoStream cs = null;
            byte[] byt;
            try
            {
                ct = mCSP.CreateDecryptor(mCSP.Key, mCSP.IV);
                byt = Convert.FromBase64String(input);
                ms = new MemoryStream();
                cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
                cs.Write(byt, 0, byt.Length);
                //cs.FlushFinalBlock();
                
            }
            catch (Exception e)
            {
                LogManager.LogError("Security.Decrypt", e.Message);
            }
            finally
            {
                if (cs != null)
                {
                    cs.Close();
                }
                if (ms != null)
                {
                    ms.Close();
                }
                if (ct != null)
                {
                    ct.Dispose();
                }
            }
            return Encoding.Default.GetString(ms.ToArray(), 0, ms.ToArray().Length);
        }

        public static void Cleanup()
        {
            mCSP.Clear();
        }        
    }
}
